home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 5 / Amiga Tools 5.iso / tools / developer-tools / aros / docs / codestyle.doc < prev   
Encoding:
Text File  |  1996-07-16  |  33.6 KB  |  919 lines

  1.  
  2.             AROS Coding Style
  3.             -----------------
  4.  
  5.         (C) 1995 AROS - The Amiga Replacement OS
  6.  
  7.             Aaron "Optimizer" Digulla
  8.               digulla@home.lake.de
  9.  
  10. 0. Preface
  11. ----------
  12.  
  13. Since many people work with you, there have to be rules about how to
  14. code. This file defines all the standards used in AROS with respect
  15. to style of source code.
  16.  
  17. 1. Introduction
  18. ----------------
  19. 1.1 General AOS Development Guidelines
  20. --------------------------------------
  21.  
  22.     * The language: Write it in ANSI C: Use full prototypes. ANSI C is the
  23.     most portable standard today and we don't write this only for the
  24.     Amiga. Always keep in mind that the source you write should compile
  25.     on PC and UNIX also.
  26.  
  27.     Some parts of the OS can't be written in C since C lacks knowledge
  28.     about the CPU (eg. interrupts and exceptions). This code is CPU
  29.     dependant and there is no way to circumvent this. For such code,
  30.     assembler has to be used. Upto now, no assembler has been chosen.
  31.     GAS is a hot candidate since it is available for all systems but
  32.     many Amiga users (and especially the hardware hackers) don't know
  33.     it and therefore we might choose something that is more "native" to
  34.     the Amiga. Don't expect it to be SAS/C's assembler or any other
  35.     commercial one, since not everyone can access it. If we choose an
  36.     assembler, it will be a public domain one so anyone can access it.
  37.  
  38.     * The "General Amiga Development Guidelines" apply (see AMIGA ROM
  39.     Kernal Reference Manual (RKRM): Libraries, third edition, page
  40.     13, "Introduction to Amiga System Libraries").
  41.  
  42.     Note: These Guidelines mostly contain "How to code well"-tips
  43.     and some Amiga-specific things, like how to wait for a signal.
  44.     Due to lack of time and copyright-issues, I did not sit down
  45.     and copy it.
  46.  
  47.     * The language for all files is ENGLISH until further notice how
  48.     the format of a multi-lingual file is.
  49.  
  50.     * The author of a file has to include his email for fast resonse
  51.     in case of bugs and problems.
  52.  
  53.     * Compatability is an issue. If you can, try to compile the code
  54.     on as many different platforms and/or compilers as you can.
  55.     Don't use Amiga-specific constructs like #pragma or __autoexit
  56.     or the like since they are not portable.
  57.  
  58.     * Make your code reentrant (ie. avoid global variables). If you
  59.     really can't, put all globals into a structure and allocate
  60.     it like this:
  61.  
  62.     Wrong:
  63.         int I;
  64.         int Should;
  65.         struct Not Do;
  66.         char This[256];
  67.  
  68.         int main (...)
  69.         {
  70.         ...
  71.  
  72.         I = 1;
  73.  
  74.         ...
  75.         } /* main */
  76.  
  77.     Good:
  78.  
  79.         struct GlobalVars
  80.         {
  81.         int gv_I;
  82.         int gv_Should;
  83.         struct Not gv_Do;
  84.         char gv_This[256];
  85.         } * global;    /* This is the _only_ global variable */
  86.  
  87.         #define I        global->gv_I
  88.         #define Should  global->gv_Should
  89.         #define This    global->gv_This
  90.  
  91.         int main (...)
  92.         {
  93.         ...
  94.  
  95.         global = AllocMem (sizeof (GlobalVars), MEMF_CLEAR);
  96.  
  97.         I = 1;
  98.  
  99.         ...
  100.         } /* main */
  101.  
  102.     This might look unneccessary, but it prevents a couple of
  103.     problems:
  104.  
  105.         * Some machines support different amounts of global
  106.         memory. Some allow 64K max, others infinite amounts,
  107.         some have problems with global vars > 32K, others don't.
  108.         * Programs that use global variables can't be made resident.
  109.         * Programmer that use global variables tend to loose control
  110.         about their variables and where they are used and changed.
  111.  
  112. 1.2 AROS Shared Libraries
  113. -------------------------
  114. 1.2.1 AROS Parts
  115. ----------------
  116.  
  117.     * Put all files for a certain topic in a new directory
  118.     * Every file implements exactly one function (this is due to
  119.     the fact that we might need link-libs for some machines).
  120.     Take a look at the advantage: Compilation is blinding fast :)
  121.     * The file has the same name as the function it contains. For now,
  122.     don't care about 8-digit-max filenames. All letters are lower-case.
  123.     * If a file needs or offers special structures which it wants
  124.     to share with others, but those into an include-file with the
  125.     same name but extension "h" in the same directory.
  126.     * Files which should be offered to the outside (eg. header-files)
  127.     go into a special public-directory.
  128.  
  129. Since this looks a bit complicated, here is an example. All files and
  130. directories go below "AOS:":
  131.  
  132.     AOS:
  133.     source/
  134.         exec/
  135.         diagnostics/
  136.             alert.c
  137.         docs/
  138.             public/
  139.             exec/
  140.             exec.doc
  141.         internal/
  142.         lists/
  143.             obj/
  144.             addhead.o addtail.o enqueue.o findname.o insert.o
  145.             remhead.o remove.o remtail.o test.o
  146.             obj_debug/
  147.             addhead.o addtail.o enqueue.o findname.o insert.o
  148.             remhead.o remove.o remtail.o test.o
  149.             public/
  150.             examples/
  151.                 exec/
  152.                 lists lists.c lists.info lists.lnk lists.o
  153.                 smakefile
  154.             include/
  155.                 exec/
  156.                 lists.h nodes.h
  157.             src/
  158.             addhead.c addtail.c enqueue.c findname.c insert.c
  159.             remhead.c remove.c remtail.c
  160.             tests/
  161.             Makefile  test    test.c    test.info  test.lnk  test.o
  162.             Makefile
  163.         Makefile
  164.         Makefile
  165.     mail/
  166.         Amigos_Mailinglist
  167.     public/
  168.         examples/
  169.         exec/
  170.             lists lists.c lists.info lists.lnk lists.o smakefile
  171.         include/
  172.         aos/
  173.             amiga.h system.h
  174.         exec/
  175.             lists.h nodes.h
  176.         lib/
  177.         exec.lib
  178.         libs/
  179.         exec.library
  180.     Makefile
  181.  
  182. Note: The files in the directories are put behind each other to save space.
  183. Otherwise this list whould extend over 4 pages...
  184.  
  185. The AOS:-directory contains "source/", "mail/" and "public/". The directories
  186. "source/" and "mail/" are for developers only. The result of the developing
  187. step goes to "public/". Everything below this directory is exported in the
  188. user-archive when we release something.
  189.  
  190. The "mail/"-directory is developer-specific. It contains mails and
  191. bug-reports and the like.
  192.  
  193. The most interesting part is the dir "source/exec/". It contains the
  194. following sub-dirs: "diagnostics/", "docs/", "internal/" and "lists/". The
  195. directories "docs/" and "internal/" are mandatory for each part of AOS. The
  196. former contains the docs for this part of AOS (exec), the latter contains
  197. all internal stuff (ie. routines and knowledge which is not neccessary to
  198. use this part, only to implement and develop it).
  199.  
  200. The other two dirs "diagnostics/" and "lists/" contain two parts of EXEC.
  201. The former contains diagnostic routines like Alert(), the other everything
  202. that is linked to EXEC-lists (eg. AddHead()). The "lists/"-dir is quite
  203. well developed, so we focus on it. The dir itself contains several other
  204. dirs and a couple of files.
  205.  
  206. The dirs "obj/" and "obj_debug/" contain compiled object-files. The files
  207. in the former directory are used for the releases, the files in the latter
  208. one contain object-files with debugging-information used during developing
  209. and testing this part. Everything contained in the "public/"-dir is copied
  210. to "AOS:public/" when a release is generated.
  211.  
  212. Most files in the "lists/"-dir contain functions for Exec-Lists, but some
  213. don't. The file "Makefile" contains the rules to compile all files (all),
  214. to compile all files with debug-options (debug), to compile the test
  215. (test), to compile a debug-version of the test (debug_test), to clean the
  216. directory and all sub-dirs (clean) and to make a distribution (dist; this
  217. mainly copies all files into "AOS:public/").
  218.  
  219. The directory "tests/" contains a Makefile and a test-program to test all
  220. features of this part. Creating and running the test should allow to check
  221. every aspect of this part in a automatic way (ie. in the end a great "make
  222. test" in the main-dir should yield a YES/NO-answer to "Does everything work
  223. ?" and a more specific answer to "If something doesn't work, what is wrong
  224. ?").
  225.  
  226. 1.2.2 AOS Parts Makefile
  227. ------------------------
  228.  
  229. The Makefile defines the following rules:
  230.  
  231.     all - Create all files that have changed anew with default options.
  232.     Object-files are places below "obj/".
  233.     debug - Like all, but the files are compiled with debug-options
  234.     and all object-files are put below "obj_debug/".
  235.     test - Create a program called "test" which tests every feature
  236.     of this part. Larger tests are done elsewhere. The test
  237.     should return the information that no errors occurred
  238.     ("No Errors") or a hint what went wrong. Other output
  239.     is optional.
  240.     debug_test - This rule should create test, too, but this time
  241.     all available debug-information should be included. Test
  242.     is to be linked with the object-files from "obj_debug/".
  243.     clean - This rule cleans the directory and all sub-dirs, too.
  244.     Cleaning means "remove any file that has been created
  245.     by the Makefile".
  246.     dist - Make a distribution. This mainly means to copy public
  247.     files in the appropriate places. If you do this in the
  248.     main directory, the Makefile will also create a couple
  249.     of archives with all sources and all binaries.
  250.  
  251. 1.2.3 Looking Into Files: C-Headers
  252. -----------------------------------
  253.  
  254. This is a sample header-file:
  255.  
  256. ------------------------------ cut --------------------------------------------
  257. #ifndef EXEC_LISTS_H
  258. #define EXEC_LISTS_H
  259. --------------- to be continued... --------------------------------------------
  260.  
  261. This has to be here in every include-header ! It is meant to prevent
  262. hassle for the user of the file. This way, the user (and we) can include
  263. this file as often has he wants or has to (through other include-headers).
  264. The name of the define can always be derived by converting all characters
  265. to upper case and replacing all non-characters by "_". The name of the
  266. file is "exec/lists.h", therefore the define is "EXEC_LISTS_H".
  267.  
  268. This is the first thing in the header file since some C preprocessors
  269. check this line and omit the whole file if the symbol is defined already.
  270.  
  271. --------------------- continue ------------------------------------------------
  272. /******************************************************************************
  273.  
  274.     FILE
  275.     $VER: exec/lists.h 1.0 (26.8.95)
  276.  
  277.     DESCRIPTION
  278.     Prototypes and macros for exec-lists.
  279.  
  280. ******************************************************************************/
  281. --------------- to be continued... --------------------------------------------
  282.  
  283. This the header for exec-lists. It contains the two entries FILE and
  284. DESCRIPTION. After FILE follows the version-information. The first
  285. entry of the version information is the name of the file. Since
  286. include-files are grouped by the part they belong to, the full
  287. name is "exec/lists.h". Then comes the version itself (1.0). The first
  288. figure gives the version, the latter the revision. The version is
  289. incremented, when something important has been done (eg. a release,
  290. a things have been renamed, something has been done which might
  291. break old software, etc.). The revision is incremented every time
  292. something small has been done (bug-fix, etc.) or when the version is
  293. not changed :)
  294.  
  295. --------------------- continue ------------------------------------------------
  296. /**************************************
  297.         Includes
  298. **************************************/
  299. #ifndef AOS_SYSTEM_H
  300. #   include <aos/system.h>
  301. #endif
  302. #ifndef EXEC_NODES_H
  303. #   include <exec/nodes.h>
  304. #endif
  305. --------------- to be continued... --------------------------------------------
  306.  
  307. The first thing in a include-header is the inclusion of all files that are
  308. neccessary to compile it WITHOUT including ANYTHING else before ! If you
  309. don't see the reason for this, just think of a first-time user who tries to
  310. use a feature of AOS. He includes the header-file for this feature and gets
  311. "error in line 15.". What will he think ? "Aren't these ^/§&% able to write
  312. correct header-files ???" or "What the hell does this (/§"&%$ include-file
  313. need to compile ?". He doesn't know, but the author of the file does and so
  314. the author does what belongs to him :)
  315.  
  316. --------------------- continue ------------------------------------------------
  317. /**************************************
  318.            Structures
  319. **************************************/
  320. --------------- to be continued... --------------------------------------------
  321.  
  322. Notices these nice headers ? They are used to give the file structure :)
  323.  
  324. --------------------- continue ------------------------------------------------
  325. /* Normal list */
  326. struct List
  327. {
  328.     struct Node * lh_Head,
  329.         * lh_Tail,
  330.         * lh_TailPred;
  331.     UBYTE      lh_Type;
  332.     BYTE      l_pad;
  333. };
  334. --------------- to be continued... --------------------------------------------
  335.  
  336. Every structure gets it's own short comment. Try to format them if possible;
  337. here, we put all types, all pointers and all names above each other. If the
  338. structure is complicated, don't hesitate to make large comments before
  339. the structure or behind each field. Make sure though, to put them below
  340. each other for improved readability.
  341.  
  342. --------------------- continue ------------------------------------------------
  343.  
  344. /* Minimal list */
  345. struct MinList
  346. {
  347.     struct Node * lh_Head,
  348.         * lh_Tail,
  349.         * lh_TailPred;
  350. };
  351.  
  352.  
  353. /**************************************
  354.            Makros
  355. **************************************/
  356. --------------- to be continued... --------------------------------------------
  357.  
  358. Another header; now we define all macros for this functions.
  359.  
  360. --------------------- continue ------------------------------------------------
  361. #undef __CAST
  362. #ifdef AOS_ALMOST_COMPATIBLE
  363. #   define CAST(x,y)    ((x)y)
  364. #else
  365. #   define CAST(x,y)    (y)
  366. #endif
  367. --------------- to be continued... --------------------------------------------
  368.  
  369. Throughout the files, the AOS_ALMOST_COMPATIBLE-define is used to
  370. mask lines which implement features or enhancements that are not
  371. 100% compatible to the original OS but will probably not break
  372. old software. For a better example, see below.
  373.  
  374. --------------------- continue ------------------------------------------------
  375. #define IsListEmpty(l) \
  376.     ( (CAST(struct List *,l)->lh_TailPred) == (struct Node *)(l) )
  377.  
  378. #define IsMsgPortEmpty(mp) \
  379.       ( (CAST(struct MsgPort *,mp)->mp_MsgList.lh_TailPred) \
  380.         == (struct Node *)(&(CAST(struct MsgPort *, mp)->mp_MsgList)) )
  381. --------------- to be continued... --------------------------------------------
  382.  
  383. These two macros are (almost) original. The difference is that the
  384. AOS-version allows to use anything as parameter of the macros. The
  385. original version whould just work with real lists or casts to lists.
  386.  
  387. --------------------- continue ------------------------------------------------
  388. #ifdef AOS_ALMOST_COMPATIBLE
  389. #   define NewList(l)       (CAST(struct List *,l)->lh_TailPred \
  390.                 = (struct Node *)(l), \
  391.                 CAST(struct List *,l)->lh_Tail = 0, \
  392.                 CAST(struct List *,l)->lh_Head \
  393.                 = (struct Node *)\
  394.                     &(CAST(struct List *,l)->lh_Tail))
  395. --------------- to be continued... --------------------------------------------
  396.  
  397. And now something which can't be find in the original sources. Here
  398. comes a couple of macros which whould be quite useful in the OS,
  399. but which are missing.
  400.  
  401. --------------------- continue ------------------------------------------------
  402. #   define GetHead(l)       (CAST(struct List *,l)->lh_Head->ln_Succ \
  403.                 ? CAST(struct List *,l)->lh_Head \
  404.                 : (struct Node *)0)
  405. #   define GetTail(l)       (CAST(struct List *,l)->lh_TailPred->ln_Succ \
  406.                 ? CAST(struct List *,l)->lh_TailPred \
  407.                 : (struct Node *)0)
  408. #   define GetSucc(n)       (CAST(struct Node *,n)->ln_Succ->ln_Succ \
  409.                 ? CAST(struct Node *,n)->ln_Succ \
  410.                 : (struct Node *)0)
  411. #   define GetPred(n)       (CAST(struct Node *,n)->ln_Pred->ln_Pred \
  412.                 ? CAST(struct Node *,n)->ln_Pred \
  413.                 : (struct Node *)0)
  414. #endif /* AOS_ALMOST_COMPATIBLE */
  415.  
  416. /******************************************************************************
  417. *****  ENDE exec/lists.h
  418. ******************************************************************************/
  419.  
  420. #endif /* EXEC_LISTS_H */
  421. ------------------------------ cut --------------------------------------------
  422.  
  423. This is the end of the file. After the "#endif" follows the comment
  424. with the name of the define above. This has to be used for every "#endif"
  425. that is "far away" of the corresponding "#if" (ie. more than about 20
  426. lines).
  427.  
  428. 2. Other Files
  429.  
  430. Throughout the directories files with the name "TODO". They contain
  431. information about the state of a project or part or whatever. The TODO-file
  432. contains a list of what has to be done, yet. The list looks like this:
  433.  
  434. ------------------------------ cut --------------------------------------------
  435. * Write the functions for exec-lists
  436. + Write good docs for exec-lists
  437. o Write exec-ports
  438.     o AddPort()
  439.     o FindPort()
  440. o etc.
  441.  
  442. BUGS:
  443. o digulla@home.lake.de metioned that not all functions have good
  444.     comments. (NTH)
  445.  
  446. o the function Alert() doesn't show that nice red frame around the
  447.     message.
  448. ------------------------------ cut --------------------------------------------
  449.  
  450. ie. every entry in introduced with a "o". If an entry extends over several
  451. lines, then the second and all folowing lines are indented.
  452.  
  453. If an entry is in work, the "o" changes to "+". When it is done, change the
  454. "+" to "*". If you want to keep records on how long you worked on it, add
  455. the time in hours in "()" after the entry. (eg. "(8h)").
  456.  
  457. Also in this file is a section which is introduced by "BUGS:". In this
  458. section, all bugs, reports, etc. are collected.
  459.  
  460.     !!! TREAT THIS PART AS READ-ONLY !!!
  461.  
  462. This way the file might get quite long, but that way it is easy to check if
  463. a bug has already gone or not or if someone is working on it. After the
  464. entry, some information follows in "()". It is a comma-separeted list of
  465. these abbreviations:
  466.  
  467.     NTH: Nice To Have. Great if someone finds the time to do it,
  468.     but it doesn't really hurt.
  469.     TODO: This one was missing in the original TODO. I have to
  470.     do it some time.
  471.     BUG: This is a bug but it doesn't need immediate fixing.
  472.     SEV: A severe bug ! This means that it really hurts and it
  473.     needs immediate work.
  474.     #h: # is the number of hours it took to fix the problem (optional)
  475.     FIX name: Name is the name of the person who fixed the bug.
  476.  
  477. 3. The Source Style
  478. -------------------
  479.  
  480. The information in the next chapters is divided into "Must Have" and
  481. "Nice To Have". "Must Have" means that source which doesn't comply
  482. to this will be rejected. "Nice To Have" means "If you follow these
  483. rules, the code will look nicer and others will understand it
  484. better" but if you object to these rules, all that will happen is
  485. a deep sigh from me :-)
  486.  
  487. 3.1 The Style "Must Have"
  488. -------------------------
  489.  
  490. The rules in this chapter are neccessary to compile the source with
  491. different compilers on different systems. If you don't follow these
  492. rules, you make your life easier but more difficult for many others.
  493. So think about it lazy lad...
  494.  
  495. 3.1.1 Includes
  496. --------------
  497.  
  498. AROS offers a layer of includes to adopt to the special needs of a
  499. certain compiler and/or hardware. All these includes can be found
  500. in the "aros" directory in the AROS includes. The meaning of these
  501. includes are described in source/aros/docs. These includes contain
  502. a great amount of knowledge about systems and hardwares. They
  503. define certain hardware independant macros to make your life
  504. easier and they define flags for you to check to see whether a
  505. certain feature is requested/neccessary/possible or not.
  506.  
  507. 3.1.2 Arguments in Registers
  508. ----------------------------
  509.  
  510. On the Amiga, it is tradition to call OS functions with the arguments
  511. in CPU registers, on other systems this is not; either because the
  512. CPU has not the same registers, either because the compiler doesn't
  513. allow for specifying a certain register for a certain parameter.
  514. To avoid breaking code for the Amiga and to avoid that we need two
  515. types of source, some very sophisticated macros have been designed to
  516. work around this problem.
  517.  
  518. First, if you need a register and your compiler says "to link a
  519. parameter with a register use this syntax", DON'T use this. Instead,
  520. name registers as "A0", "D3" etc. These are in fact macros which
  521. are expanded into something your compiler can understand. This is
  522. done automatically; all you have to do is to include <aros/libcall.h>.
  523.  
  524. See source/aros/docs/libcall.doc for a description how to do it.
  525. Most of the time, you need not worry, since the headers for all
  526. library functions are generated with a script and you need only
  527. fill in the source for the function.
  528.  
  529. 3.1.3 Autodocs and AROS
  530. -----------------------
  531.  
  532. AROS doesn't use the Autodoc standard for OS functions because
  533. Autodocs are too limited for this. Our format, however, can be
  534. converted into Autodocs with little effort.
  535.  
  536. Here is an example for a complete header:
  537.  
  538. --------- header of source/exec/kernel/src/rawdofmt.c ------------------------
  539. /*
  540.     $Id$
  541.     $Log$
  542. ----- header of source/exec/kernel/src/rawdofmt.c (to be continued) ----------
  543.  
  544. These are for RCS. $Id$ is replaced by the version, the name of the
  545. file and the person that changed it the last time. $Log$ is replaced
  546. by a list of all changed made to the file with date and name of the
  547. person that did it.
  548.  
  549. -------- header of source/exec/kernel/src/rawdofmt.c (continued) -------------
  550.     Desc:
  551. ----- header of source/exec/kernel/src/rawdofmt.c (to be continued) ----------
  552.  
  553. Here comes the short description. With Autodocs, this would have been in
  554. the NAME section. NOTE: This part of the header is subject to change. If it
  555. is changed all sources are converted automatically.
  556.  
  557. -------- header of source/exec/kernel/src/rawdofmt.c (continued) -------------
  558.     Lang: english
  559. ----- header of source/exec/kernel/src/rawdofmt.c (to be continued) ----------
  560.  
  561. The language of the header. This is for future expansion so we can offer
  562. Autodocs in different languages. NOTE: This part of the header is subject
  563. to change. If it is changed all sources are converted automatically.
  564.  
  565. -------- header of source/exec/kernel/src/rawdofmt.c (continued) -------------
  566. */
  567. #include "exec_intern.h"
  568. #include "machine.h"
  569. ----- header of source/exec/kernel/src/rawdofmt.c (to be continued) ----------
  570.  
  571. Here is a list of internal includes, ie. includes that are neccessary to
  572. compile this file but NOT to use the function !
  573.  
  574. -------- header of source/exec/kernel/src/rawdofmt.c (continued) -------------
  575. /*****************************************************************************
  576.  
  577.     NAME */
  578.     #include <exec/types.h>
  579.     #include <clib/exec_protos.h>
  580. ----- header of source/exec/kernel/src/rawdofmt.c (to be continued) ----------
  581.  
  582. This is the header of the file. Since every file contains only a single
  583. function, there is no special file-header but only the header of the
  584. function. By making use of C-comments, we mix source-code and documentation
  585. in a way which makes it unneccessary to write code twice. This also helps
  586. in writing working code since the documentation is always up-to-date.
  587.  
  588. The first thing are the include-files the user of this function needs. Any
  589. internal includes would go in front of the first line. For this function,
  590. we need the header-file for lists and the prototypes for exec-functions.
  591.  
  592. -------- header of source/exec/kernel/src/rawdofmt.c (continued) -------------
  593.     __AROS_LH4I(APTR, RawDoFmt,
  594. ----- header of source/exec/kernel/src/rawdofmt.c (to be continued) ----------
  595.  
  596. Here we use a macro to make the prototype usable for other compilers on
  597. other systems. For a complete description of the __AROS_LH-macros, look
  598. into source/aros/docs/libcall.doc. Here the macro declares a function that
  599. is named "RawDoFmt", returns APTR, has 4 arguments and doesn't need the
  600. libbase (see below).
  601.  
  602. -------- header of source/exec/kernel/src/rawdofmt.c (continued) -------------
  603. /*  SYNOPSIS */
  604.     __AROS_LA(UBYTE   *, formatString, A0),
  605.     __AROS_LA(APTR     , dataStream,   A1),
  606.     __AROS_LA(VOID_FUNC, putChProc,    A2),
  607.     __AROS_LA(APTR     , putChData,    A3),
  608. ----- header of source/exec/kernel/src/rawdofmt.c (to be continued) ----------
  609.  
  610. These are all arguments. Note the use of the C comment. This way, the
  611. arguments have to be specified only once! No need to worry if the types and
  612. names in the header really match the ones used in the part of the file that
  613. the compiler actually sees.
  614.  
  615. Every argument is encapsulated in a __AROS_LA-macro which sorts the order
  616. of arguments (some compilers need the register after the type and the
  617. like). We specify the type, the name and the CPU register in which the
  618. argument is passed. The CPU register is safely ignored if it can't be used
  619. (eg. because the CPU has no such register or the compiler doesn't allow to
  620. specify in which register a parameter has to be passed in a.s.o.).
  621.  
  622. The parameter putChProc is declared as type "VOID_FUNC" due to the fact
  623. that the use of the macro makes it impossible to declare it as
  624. "void(*putChProc)()". There are more of these types in
  625. include/aros/libcall.h.
  626.  
  627. Note that the types, stars and parameter-names are put below each other to
  628. increase readability.
  629.  
  630. -------- header of source/exec/kernel/src/rawdofmt.c (continued) -------------
  631. /*  LOCATION */
  632.     struct ExecBase *, SysBase, 87, Exec)
  633. ----- header of source/exec/kernel/src/rawdofmt.c (to be continued) ----------
  634.  
  635. These are the last four parameters of all __AROS_LH-macros. They
  636. declare the type and name of the libbase, the LVO offset of the function
  637. and the name of the library for this function (in this order). The
  638. first two arguments are ignored if LVOs are not used for this system.
  639. The LVO itself is always ignored, but it has to be somewhere and there
  640. was no much better place for it. The last argument is used to put a
  641. common prefix before all functions of a library so there are no problems
  642. with linking the library to code that needs stubs to call library
  643. functions (same names for functions and the like).
  644.  
  645. There are other flavours of __AROS_LH-macros which allow to declare
  646. a function (prototype in a include file) and to call it (using LVOs
  647. if neccessary).
  648.  
  649. -------- header of source/exec/kernel/src/rawdofmt.c (continued) -------------
  650. /*  FUNCTION
  651.     printf-style formatting function with callback hook.
  652. ----- header of source/exec/kernel/src/rawdofmt.c (to be continued) ----------
  653.  
  654. Now we give a complete description of what the function does. This includes
  655. all features and usages but excludes return-values and parameters if not
  656. absolutely neccessary.
  657.  
  658. -------- header of source/exec/kernel/src/rawdofmt.c (continued) -------------
  659.     INPUTS
  660.     FormatString - Pointer to the format string with any of the following
  661.                stream formatting options allowed:
  662.  
  663.                %[leftalign][minwidth.][maxwidth][size][type]
  664.  
  665.                leftalign - '-' means align left. Default: align right.
  666.                minwidth  - minimum width of field. Defaults to 0.
  667.                maxwidth  - maximum width of field (for strings only).
  668.                    Defaults to no limit.
  669.                size     - 'l' means longword. Defaults to word.
  670.                type     - 'b' BCPL string. A BPTR to a one byte
  671.                        byte count followed by the characters.
  672.                    'c' single character.
  673.                    'd' signed decimal number.
  674.                    's' C string. NUL terminated.
  675.                    'u' unsigned decimal number.
  676.                    'x' unsigned sedecimal number.
  677.  
  678.     dataStream   - Array of the data items.
  679.     putChProc    - Callback function. Called for each character, including
  680.                the NUL terminator.
  681.     putChData    - Data propagated to each call of the callback hook.
  682. ----- header of source/exec/kernel/src/rawdofmt.c (to be continued) ----------
  683.  
  684. Here are the parameters. Don't name the type; the name is enough. The
  685. parameter is separated from the rest of the description by a "-" (minus).
  686. The description is indented, if it doesn't fit in a single line. If you
  687. want to group parameters, put them into a comma-separated list. If this
  688. list extends over more than one line, it is NOT indented. It is allowed to
  689. put each parameter in such a list in his own line. The last parameter in
  690. the list is not followed by a comma (just in case...).
  691.  
  692. The description should contain every bit of information to understand what
  693. this parameter does. If a parameter is a return value (ie. the functions
  694. puts something in it and ignores the old value), you can omit it here and
  695. explain it in the next section. If the function modifies the parameter, you
  696. should explain it here (at least the part of the explanation which tells
  697. with which values in this parameter the function can be called).
  698.  
  699. -------- header of source/exec/kernel/src/rawdofmt.c (continued) -------------
  700.     RESULT
  701.     Pointer to the rest of the dataStream.
  702. ----- header of source/exec/kernel/src/rawdofmt.c (to be continued) ----------
  703.  
  704. Here we explain what the function returns or what it changes. For example
  705. the RESULT of Supervisor() is that we are in supervisor mode now.
  706.  
  707. -------- header of source/exec/kernel/src/rawdofmt.c (continued) -------------
  708.     NOTES
  709.     The field size defaults to words which may be different from the
  710.     default integer size of the compiler.
  711. ----- header of source/exec/kernel/src/rawdofmt.c (to be continued) ----------
  712.  
  713. Mention all aspects of the function that the user of it should look out for
  714. (eg. unexpected results, problems, special circumstances, if the function
  715. breaks on NULL-parameters or if it doesn't).
  716.  
  717. -------- header of source/exec/kernel/src/rawdofmt.c (continued) -------------
  718.     EXAMPLE
  719.     // build a sprintf style function
  720.  
  721.     static void callback (UBYTE chr, UBYTE **data)
  722.     {
  723.         *(*data)++ = chr;
  724.     }
  725.  
  726.     void my_sprintf (UBYTE *buffer, UBYTE *format, ...)
  727.     {
  728.         RawDoFmt (format, &format+1, callback, &buffer);
  729.     }
  730. ----- header of source/exec/kernel/src/rawdofmt.c (to be continued) ----------
  731.  
  732. This section should contain a most complete example of how to use
  733. the function. Since one cannot use normal C-Style comments here,
  734. there are a couple of ways to circumvent this:
  735.  
  736.     a) Use "EXAMPLE */" instead of "EXAMPLE" and put the whole
  737.     example in a "#ifdef COMPILE_EXAMPLE"..."#endif" block.
  738.     b) Use C++-style comments "// This is a comment."
  739.     c) Use Autodoc-Style C comments: "\* This is a comment *\"
  740.  
  741. All these ways are accepted by the Autodoc compiler.
  742.  
  743. -------- header of source/exec/kernel/src/rawdofmt.c (continued) -------------
  744.     BUGS
  745.     PutChData cannot be modified from the callback hook.
  746. ----- header of source/exec/kernel/src/rawdofmt.c (to be continued) ----------
  747.  
  748. Now here for the interesting part: Things that should but don't work.
  749. If you can, name a workaround.
  750.  
  751. -------- header of source/exec/kernel/src/rawdofmt.c (continued) -------------
  752.     SEE ALSO
  753.     printf(), sprintf(), vsprintf(), fprintf()
  754. ----- header of source/exec/kernel/src/rawdofmt.c (to be continued) ----------
  755.  
  756. Specify function here, which work on the same data (eg. OpenWindow()
  757. should mention all other functions working on windows). Always remember:
  758. Too much information is less frustrating than not enough information.
  759.  
  760. -------- header of source/exec/kernel/src/rawdofmt.c (continued) -------------
  761.     INTERNALS
  762. ----- header of source/exec/kernel/src/rawdofmt.c (to be continued) ----------
  763.  
  764. This section is for experts only. For the mortal user, it is omitted.
  765. Name things here someone who tries to understand your code should know.
  766.  
  767. -------- header of source/exec/kernel/src/rawdofmt.c (continued) -------------
  768.     HISTORY
  769.     22-10-95    created by m. fleischer
  770. ----- header of source/exec/kernel/src/rawdofmt.c (to be continued) ----------
  771.  
  772. This part is subject of change, too, since RCS is doing it already. Maybe
  773. only major changes will be mentioned here.
  774.  
  775. -------- header of source/exec/kernel/src/rawdofmt.c (continued) -------------
  776. ******************************************************************************/
  777. ----------- header of source/exec/kernel/src/rawdofmt.c (end) ----------------
  778.  
  779. The terminator of the header. The AROS-Header-To-Autodoc converter stops
  780. here. The rest of the file is ignored.
  781.  
  782. 3.2 The Style "Nice To Have"
  783. ----------------------------
  784.  
  785. Now I explain my favourite style to code. Since I like structured code,
  786. I insert quite a lot of space in my code. The result looks good but
  787. on the other hand you need a lot of resolution on you screen to see
  788. more than a small portion of my code.
  789.  
  790. 3.2.1 Indent
  791. ------------
  792.  
  793. One indent level is 4 spaces. Two levels of indentation are sometimes
  794. a tab. Tabs are is alway set every 8 spaces.
  795.  
  796. 3.2.2 Comments
  797. --------------
  798.  
  799. Comments are aligned with the rest of the source:
  800.  
  801.     if (...)
  802.     {
  803.     }
  804.  
  805.     /* This is a comment */
  806.     a = 1;
  807.  
  808. No space follows a comment, but at least one emtpy line goes before it.
  809. If a comment is long, it looks like this:
  810.  
  811.     a = 0;
  812.  
  813.     /*
  814.     This
  815.     is a
  816.     very
  817.     long
  818.     comment (somehow).
  819.     */
  820.     a = 1;
  821.  
  822. I don't use the "*-before-every-line" since that results in code where the
  823. comments don't reflect the recent changes since that would mean to remore
  824. all *'s, change the comment and the reinsert the *'s again.
  825.  
  826. 3.2.2 Blocks
  827. ------------
  828.  
  829. Blocks look like this:
  830.  
  831. int foo (int a)
  832. {
  833.     if (...)
  834.     {
  835.     while (...)
  836.     {
  837.     }
  838.     } /* ... */
  839. } /* foo */
  840.  
  841. The braces are above each other and the text in a block is
  842. indented once. Note the use of comments here. Functions always get
  843. an end-comment with the name of the function. Blocks get a
  844. short description of the header of the block if the first and
  845. the last line are about 20 lines away.
  846.  
  847. 3.2.3 Spaces
  848. ------------
  849.  
  850. I insert a space...
  851.  
  852.     - after a variable, function or C keyword
  853.     - before and after operators
  854.  
  855. Sometimes a insert more than one space to get this:
  856.  
  857.  
  858.     struct RastPort * rp;
  859.     int           count;
  860.  
  861.     some->struct               = 0;
  862.     some->even.more.complicated.struct = 1;
  863.     count                   = 0;
  864.  
  865. ie. a tabular look.
  866.  
  867. Empty lines are inserted whenever the semantic changes:
  868.  
  869.     if (a)
  870.     {
  871.     } /* a != 0 */
  872.     if (b)
  873.     {
  874.     } /* b != 0 */
  875.  
  876.     a = 1;
  877.  
  878.     call (a,       function);
  879.     call (another, function);
  880.  
  881.     ...
  882.  
  883. ie. the two if()'s aren't separated, then an empty line and an assignment,
  884. an empty line and a couple of function calls.
  885.  
  886. 3.2.4 Breaking Long Expressions
  887. -------------------------------
  888.  
  889. Long expressions look like this:
  890.  
  891.     if (maybe
  892.         || sure
  893.         || (a
  894.         && this_is_never_true (but,
  895.             who, knows)
  896.         && TRUE
  897.         )
  898.         )
  899.  
  900. This looks unfamiliar, but it shows at a glance what part of the expression
  901. belongs to which other part and how the sub-expressions are connected.
  902.  
  903. These are the rules:
  904.  
  905.     a) Each part of the expressions get's it's ownline except it is
  906.     the first part.
  907.     b) An operator or a "(" are the first things in a line. If there
  908.     are both, the operator comes first.
  909.     c) If a subexpression (eg. a function call) is too long, it is
  910.     split at a space and indented two times (to avoid visual
  911.     conflicts with subexpressions at a lower level).
  912.  
  913. Advantages:
  914. - Most parts of the expression can be inserted or removed with line operations
  915.     (ie. delete whole line or insert a new line).
  916. - No need to reformat the whole expression if you inserted or deleted
  917.     a lot.
  918. - Parenthese levels are easy distinguishable.
  919.